package com.yoomiito.app.widget.state;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;


import com.yoomiito.app.R;
import com.yoomiito.app.utils.NetworkUtils;

import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;


/**
 * 布局切换视图
 * 修改来至 https://github.com/lufficc/StateLayout
 */
public class StateLayout extends FrameLayout {
    private View contentView;

    private View emptyView;
    private View emptyContentView;

    private View errorView;
    private View errorContentView;

    private View progressView;
    private ImageView progressImageView;
    private View progressContentView;

    private TextView emptyTextView;
    private TextView errorTextView;
    private TextView progressTextView;

    private ImageView errorImageView;
    private ImageView emptyImageView;
    private AnimationDrawable mProgressAnim;

    private View currentShowingView;

    private TextView emptyPromptTextView;
    private ViewAnimProvider viewSwitchAnimProvider;

    public static final int EMPTY_VIEW = 1;
    public static final int PROGRESS_VIEW = 2;
    public static final int ERROR_VIEW = 3;

    public StateLayout(Context context) {
        this(context, null);
    }


    public StateLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public StateLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        parseAttrs(context, attrs);

        emptyView.setVisibility(View.GONE);

        errorView.setVisibility(View.GONE);

        progressView.setVisibility(View.GONE);

        currentShowingView = contentView;
    }

    private void parseAttrs(Context context, AttributeSet attrs) {
        LayoutInflater inflater = LayoutInflater.from(context);

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.StateLayout, 0, 0);
        int progressViewId;
        Drawable errorDrawable;
        Drawable emptyDrawable;
        try {
            errorDrawable = a.getDrawable(R.styleable.StateLayout_errorDrawable);
            emptyDrawable = a.getDrawable(R.styleable.StateLayout_emptyDrawable);
            progressViewId = a.getResourceId(R.styleable.StateLayout_progressView, -1);
        } finally {
            a.recycle();
        }

        if (progressViewId != -1) {
            progressView = inflater.inflate(progressViewId, this, false);
        } else {
            progressView = inflater.inflate(R.layout.layout_progress, this, false);
//            progressTextView = (TextView) progressView.findViewById(R.id.progressTextView);
//            progressImageView = (ImageView) progressView.findViewById(R.id.progress_wheel);
//            progressContentView = progressView.findViewById(R.id.progress_content);
        }

        addView(progressView);

        errorView = inflater.inflate(R.layout.layout_error, this, false);
//        errorContentView = errorView.findViewById(R.id.network_btn);
        addView(errorView);

        emptyView = inflater.inflate(R.layout.layout_empty, this, false);
//        emptyContentView = emptyView.findViewById(R.id.empty_content);
//        emptyTextView = (TextView) emptyView.findViewById(R.id.emptyTextView);
//        emptyPromptTextView = (TextView) emptyView.findViewById(R.id.emptyPromptTextView);
//        emptyImageView = (ImageView) emptyView.findViewById(R.id.emptyImageView);
//        if (emptyDrawable != null) {
//            emptyImageView.setImageDrawable(emptyDrawable);
//        } else {
//            emptyImageView.setImageResource(R.drawable.bg_no_record);
//        }
        addView(emptyView);
        /******************************************************************************************/
/*        noNetworkContentView = inflater.inflate(R.layout.view_network, this, false);
        noNetworkContentView.setVisibility(View.GONE);
        noNetworkView = (Button) noNetworkContentView.findViewById(R.id.network_btn);
        addView(noNetworkContentView);*/
    }

    private void checkIsContentView(View view) {
        if (contentView == null && view != errorView && view != progressView && view != emptyView) {
            contentView = view;
            currentShowingView = contentView;
        }
    }

    public ImageView getErrorImageView() {
        return errorImageView;
    }

    public ImageView getEmptyImageView() {
        return emptyImageView;
    }

    public void setViewSwitchAnimProvider(ViewAnimProvider viewSwitchAnimProvider) {
        if (viewSwitchAnimProvider != null) {
            this.viewSwitchAnimProvider = viewSwitchAnimProvider;
            this.showAnimation = viewSwitchAnimProvider.showAnimation();
            this.hideAnimation = viewSwitchAnimProvider.hideAnimation();
        }
    }


    public boolean isShouldPlayAnim() {
        return shouldPlayAnim;
    }

    public void setShouldPlayAnim(boolean shouldPlayAnim) {
        this.shouldPlayAnim = shouldPlayAnim;
    }

    private boolean shouldPlayAnim = true;
    private Animation hideAnimation;
    private Animation showAnimation;

    public Animation getShowAnimation() {
        return showAnimation;
    }

    public void setShowAnimation(Animation showAnimation) {
        this.showAnimation = showAnimation;
    }

    public Animation getHideAnimation() {
        return hideAnimation;
    }

    public void setHideAnimation(Animation hideAnimation) {
        this.hideAnimation = hideAnimation;
    }

    private void switchWithAnimation(final View toBeShown) {
        final View toBeHided = currentShowingView;
        if (toBeHided == toBeShown)
            return;
        if (shouldPlayAnim) {
            if (toBeHided != null) {
                if (hideAnimation != null) {
                    hideAnimation.setAnimationListener(new Animation.AnimationListener() {
                        @Override
                        public void onAnimationStart(Animation animation) {

                        }

                        @Override
                        public void onAnimationEnd(Animation animation) {
                            toBeHided.setVisibility(GONE);
                        }

                        @Override
                        public void onAnimationRepeat(Animation animation) {

                        }
                    });
                    hideAnimation.setFillAfter(false);
                    toBeHided.startAnimation(hideAnimation);
                } else
                    toBeHided.setVisibility(GONE);
            }
            if (toBeShown != null) {
                if (toBeShown.getVisibility() != VISIBLE)
                    toBeShown.setVisibility(VISIBLE);
                currentShowingView = toBeShown;
                if (showAnimation != null) {
                    showAnimation.setFillAfter(false);
                    toBeShown.startAnimation(showAnimation);
                }
            }
        } else {
            if (toBeHided != null) {
                toBeHided.setVisibility(GONE);
            }
            if (toBeShown != null) {
                currentShowingView = toBeShown;
                toBeShown.setVisibility(VISIBLE);
            }
        }

    }

    public void setEmptyContentViewMargin(int left, int top, int right, int bottom) {
        ((LayoutParams) emptyContentView.getLayoutParams()).setMargins(left, top, right, bottom);
    }

    public void setErrorContentViewMargin(int left, int top, int right, int bottom) {
        ((LayoutParams) errorContentView.getLayoutParams()).setMargins(left, top, right, bottom);
    }

    public void setProgressContentViewMargin(int left, int top, int right, int bottom) {
        ((LayoutParams) progressContentView.getLayoutParams()).setMargins(left, top, right, bottom);
    }

    public void setInfoContentViewMargin(int left, int top, int right, int bottom) {
        ((LayoutParams) emptyContentView.getLayoutParams()).setMargins(left, top, right, bottom);
        ((LayoutParams) errorContentView.getLayoutParams()).setMargins(left, top, right, bottom);
        ((LayoutParams) progressContentView.getLayoutParams()).setMargins(left, top, right, bottom);
    }


    public void showContentView() {
        if (mProgressAnim != null) {
            mProgressAnim.stop();
        }
        switchWithAnimation(contentView);
    }

    public View getContentView() {
        return contentView;
    }

    public void showEmptyView() {
        showEmptyView(null);
    }

    public void showEmptyView(boolean isShowHideText) {
        showEmptyView(null, isShowHideText);
    }


    public void showEmptyView(String msg, boolean isShowPromptText) {
        showEmptyView(msg, isShowPromptText, null);
    }

    public void showEmptyView(String msg, boolean isShowPromptText, String text) {
        if (isShowPromptText) {
            emptyPromptTextView.setVisibility(View.GONE);
        } else {
            if (!TextUtils.isEmpty(text))
                emptyPromptTextView.setText(text);
        }
        showEmptyView(msg);
    }

    public void showEmptyView(String msg) {
        onHideContentView();
        if (!TextUtils.isEmpty(msg))
            emptyTextView.setText(msg);
        switchWithAnimation(emptyView);
    }

    public void showEmptyView(int resId, String msg) {
        if (resId != 0) {
            emptyImageView.setImageResource(resId);
        }
        showEmptyView(msg);
    }

    public void showErrorView() {
        showErrorView(null);
    }

    public void showErrorView(String msg) {
        onHideContentView();
        if (msg != null)
            errorTextView.setText(msg);
        switchWithAnimation(errorView);
    }

    public void showProgressView() {
        showProgressView(null);
    }

    public void showProgressView(String msg) {
        showProgress(msg);
    }

    public void showUiContentView() {
        if (NetworkUtils.getNetworkType() == NetworkUtils.NET_TYPE_WIFI) {
            Observable.empty().delay(300, TimeUnit.MILLISECONDS).subscribe(v -> showContentView());
        } else {
            showContentView();
        }
    }

    public void showUiProgressView() {
        if (NetworkUtils.getNetworkType() == NetworkUtils.NET_TYPE_WIFI) {
            Observable.empty().delay(300, TimeUnit.MILLISECONDS).subscribe(v -> showProgressView());
        } else {
            showProgressView();
        }
    }

    private void showProgress(String msg) {
        onHideContentView();
        if (msg != null)
            progressTextView.setText(msg);
        if (mProgressAnim == null) {
            mProgressAnim = (AnimationDrawable) progressImageView.getBackground();
        }
        mProgressAnim.start();
        switchWithAnimation(progressView);
    }


    public void setErrorAction(final OnClickListener onErrorButtonClickListener) {
        errorContentView.setOnClickListener(onErrorButtonClickListener);
    }

    public void setEmptyAction(final OnClickListener onEmptyButtonClickListener) {
        emptyView.setOnClickListener(onEmptyButtonClickListener);
    }


    public void setErrorAndEmptyAction(final OnClickListener errorAndEmptyAction) {
        errorView.setOnClickListener(errorAndEmptyAction);
        emptyView.setOnClickListener(errorAndEmptyAction);
    }

    protected void onHideContentView() {
        contentView.setVisibility(View.GONE);
    }


    public void switchView(View view, int type) {
        switch (type) {
            case EMPTY_VIEW:
                if (view != emptyView) {
                    removeView(emptyView);
                    view.setVisibility(View.GONE);
                    super.addView(view);
                    emptyView = view;
                }
                break;
            case PROGRESS_VIEW:
                if (view != progressView) {
                    removeView(progressView);
                    view.setVisibility(View.GONE);
                    super.addView(view);
                    progressView = view;
                }
                break;
            case ERROR_VIEW:
                if (view != errorView) {
                    removeView(errorView);
                    view.setVisibility(View.GONE);
                    super.addView(view);
                    errorView = view;
                }
                break;
        }
    }

    /**
     * addView
     */
    @Override
    public void addView(View child) {
        checkIsContentView(child);
        super.addView(child);
    }

    @Override
    public void addView(View child, int index) {
        checkIsContentView(child);
        super.addView(child, index);
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        checkIsContentView(child);
        super.addView(child, index, params);
    }

    @Override
    public void addView(View child, ViewGroup.LayoutParams params) {
        checkIsContentView(child);
        super.addView(child, params);
    }

    @Override
    public void addView(View child, int width, int height) {
        checkIsContentView(child);
        super.addView(child, width, height);
    }

    @Override
    protected boolean addViewInLayout(View child, int index, ViewGroup.LayoutParams params) {
        checkIsContentView(child);
        return super.addViewInLayout(child, index, params);
    }

    @Override
    protected boolean addViewInLayout(View child, int index, ViewGroup.LayoutParams params,
                                      boolean preventRequestLayout) {
        checkIsContentView(child);
        return super.addViewInLayout(child, index, params, preventRequestLayout);
    }
}
